Qt 软件开发框架(详细版) 您所在的位置:网站首页 Unity MMO客户端服务端技术架构设计图 Qt 软件开发框架(详细版)

Qt 软件开发框架(详细版)

2024-07-07 14:07| 来源: 网络整理| 查看: 265

该文章用图例+代码方式演示了,一个线上软件基本框架(精简)。开发工具Qt+VS2015

一. 基本要素

这里会用简单的图例和完整代码(这里以Qt代码为例),说明一个线上软件基本的框架。

一个线上windows软件,一般分为几个大的部分

1 UI模块

负责处理来自业务逻辑层或者其它模块的数据展示

2 网络模块

A http、https请求 B websocket(该文章不做赘述) 封装post或get请求,处理请求返回、超时等

3 业务逻辑模块

这里主要处理的是网络模块返回数据的处理,并把结果通知UI模块

4 中间层

负责关联网络模块和业务逻辑模块

5 独立模块(守护进程、更新模块、日志收集模块…)

该文章不做赘述

这里UI模块并非纯UI,其中也有业务逻辑处理。 UI模块和业务逻辑模块 可以做成更低耦合,但是会有降低效率的代价

二. 图例部分

在这里插入图片描述

这里用精简代码演示了 1 从用户操作UI(调用UIMainWnd::sendAsk()) 2 发送网络请求(Network::_post(),Network::_get()) 3 到请求结果返回(Network::requestFinished()) 4 对返回数据处理(BusinessLogicManager::onAskAction()) 5 通知UI模块显示(UIMainWnd::on_ask_action())

三. 代码部分

这里使用精简Qt代码演示

1 配置文件模块 #pragma once /********************************************************************* *@file ConfigDef.h *@brief 管理枚举enum、定义define、QString... *@author *@date *********************************************************************/ ///@ 网路请求消息结构 typedef struct _tagNetMessage { QString _type; // 类型 int _flag; // 标识 QString _url; // 接口Url QString _method; // 请求方式 QByteArray _byte; // 参数 }NetMessage; // 请求接口 /// @brief 发送聊天消息 #define API_POST_ASK_ACTION "http://www.xxxx.com/tztv/ask_action.php" // 请求类型标识 /// @brief 消息类型(用来在发送和接收网络请求时,区分是哪种消息类型) namespace RequestType { #define REQUEST_TYPE_ASK_ACTION "ask_action" // 直播间发送文本消息 }; 2 UI模块 // 头文件 /********************************************************************* *@file UIMainWnd.h *@brief 交互界面 *@author *@date *********************************************************************/ #pragma once #include class UIMainWnd : public QWidget { Q_OBJECT public: UIMainWnd(QWidget *parent = Q_NULLPTR); ~UIMainWnd(); private Q_SLOTS: // 文本消息(网络请求返回处理) void on_ask_action(bool, const QString&, int _error_code = 0); private: void initUI(); // 发送文本消息(网络请求) void sendText(const QString&_text); }; // 源文件 UIMainWnd::UIMainWnd(QWidget *parent) : QWidget(parent) { initUI(); } UIMainWnd::~UIMainWnd() { } void UIMainWnd::initUI() { connect(BridgeManager::instance().businessIns(), &BusinessLogicManager::sigAskAction, this, &UIDiscuss::on_ask_action); } /** * 发送文本消息 */ void UIMainWnd::sendText(const QString&_text) { QByteArray data; data.append("channel=" + DataMgr::instance().getLocalUserInfo()._user_group); std::string str = Utils::_urlencode(_text.toStdString()); QString msg_param = QString::fromStdString(str); data.append("&message=" + msg_param); data.append("&client_type=client"); NetMessage msg; msg._type = REQUEST_TYPE_ASK_ACTION; msg._flag = rt_ask_action; msg._url = API_POST_ASK_ACTION; msg._method = "post"; msg._byte = data; BridgeManager::instance().businessIns()->networkRequest(msg); } // 文本消息 void UIMainWnd::on_ask_action(bool bsuccess, const QString&_content, int _error_code) { // 处理来自业务逻辑层的消息 if (bsuccess) { } else { } } 2 网络模块

分为网络模块和网络管理模块,以及超时处理,cookie处理 1)网络模块和超时处理

/********************************************************************* *@file Network.h *@brief 网络模块封装 *@author *@date *********************************************************************/ #pragma once #include #include #include class Network : public QObject { Q_OBJECT public: Network(QObject *parent); ~Network(); void _get(const QUrl& _url); void _post(const QUrl& _url, const QByteArray& _bytes); void _setType(const QString& _type,); // 设置该请求的类型RequestType void _setCookieJar(QNetworkCookieJar *cookieJar); //设置cookie Q_SIGNALS: // 网络模块->通知网络管理层 /// 网络请求返回数据 void sigReply(const QString &_type_net, const QByteArray &_byte_array); /// 网络请求失败 void sigReplyError(const QString &_type_net, const int &_error_code, const QString &_error_string); /// 网络请求超时 void sigTimeout(const QString& _type_net); private Q_SLOTS: // 对于网络请求返回的处理一般有三种情况:返回成功,返回失败,请求超时 void requestFinished(QNetworkReply* _reply); // 网络请求返回处理(返回成功、返回失败) void on_timeout(); // 超时处理 private: QString m_netType = tr(""); // 配置模块中RequestType QNetworkRequest m_httpRequest; QNetworkAccessManager m_networkAccessManager; }; // 超时处理 class QReplyTimeout : public QObject { Q_OBJECT public: QReplyTimeout(QNetworkReply *reply, const int timeout); signals: void sigTimeout(); private slots: void on_timeout(); }; #include "Network.h" Network::Network(QObject *parent) : QObject(parent) { QMetaObject::Connection connRet = QObject::connect(&m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*))); Q_ASSERT(connRet); } Network::~Network() { m_networkAccessManager.disconnect(); } void Network::_setType(const QString& _type) { m_netType = _type; } void Network::_setCookieJar(QNetworkCookieJar *cookieJar) { m_networkAccessManager.setCookieJar(cookieJar); } void Network::_get(const QUrl& _url) { m_httpRequest.setUrl(_url); QNetworkReply *_reply = m_networkAccessManager.get(m_httpRequest); // 请求超时 QReplyTimeout *pTimeout = new QReplyTimeout(_reply, 5000); connect(pTimeout, &QReplyTimeout::sigTimeout, this, &Network::on_timeout); } void Network::_post(const QUrl& _url, const QByteArray& _bytes) { QNetworkRequest _request; _request.setUrl(_url); QNetworkReply *_reply = m_networkAccessManager.post(_request, _bytes); // 请求超时 QReplyTimeout *pTimeout = new QReplyTimeout(_reply, 5000); connect(pTimeout, &QReplyTimeout::sigTimeout, this, &Network::on_timeout); } void Network::requestFinished(QNetworkReply* _reply) { if (_reply->error() == QNetworkReply::NoError) {// request success QByteArray _byteArray = _reply->readAll(); // 这里是日志,方便在日志文件中查看。关于日志生成的看后续文章 QString _str_error = QString("%1 : request_reply_source_data = %2").arg(m_netType).arg(QString(_byteArray)); LINFO(L"%s", _str_error.toStdWString().c_str()); emit sigReply(m_netType, _byteArray); } else {// request fail int _error_code = _reply->error(); QString _log_error = QString("%1 : request_reply_network_error_code = %2").arg(m_netType).arg(QString::number(_error_code)); LINFO(L"%s", _log_error.toStdWString().c_str()); QString _error_str = _reply->errorString(); emit sigReplyError(m_netType, _error_code, _error_str); } _reply->deleteLater(); } void Network::on_timeout() {// request timeout QNetworkReply* _reply = (QNetworkReply*)sender(); int _error_code = _reply->error(); QString _log_error = QString("%1 : request_reply_timeout = %2").arg(m_netType).arg(QString::number(_error_code)); LINFO(L"%s", _log_error.toStdWString().c_str()); emit sigTimeout(m_netType); } QReplyTimeout::QReplyTimeout(QNetworkReply *reply, const int timeout) : QObject(reply) { Q_ASSERT(reply); if (reply && reply->isRunning()) { // 启动单次定时器 QTimer::singleShot(timeout, this, SLOT(on_timeout())); } } void QReplyTimeout::on_timeout() { // 处理超时 QNetworkReply *reply = static_cast(parent()); if (reply->isRunning()) { reply->abort(); reply->deleteLater(); emit sigTimeout(); } }

2)网络管理模块

#pragma once /********************************************************************* *@file NetWorkManager.h *@brief 网络管理层(接收来自业务层请求,把请求结果返回业务层,通过中间层关联) *@author *@date *********************************************************************/ #include class NetworkManager : public QObject { Q_OBJECT public: NetworkManager(QObject *parent); ~NetworkManager(); Q_SIGNALS: /// @网络层->业务层(网络层通知业务层) void sigReply(const QString& _type, const QByteArray& _byte_array); void sigReplyError(const QString &_type_net, const int &_error_code, const QString &_error_string); void sigTimeout(const QString& _type_net); public Q_SLOTS: /// @来自业务层的请求 void on_net_request_activated(NetMessage &); }; #include "NetworkManager.h" #include "Network.h" #include "NetworkCookie.h" #include NetworkManager::NetworkManager(QObject *parent) : QObject(parent) { //gu_networkManager->activeConfiguration(); } NetworkManager::~NetworkManager() { } void NetworkManager::on_net_request_activated(NetMessage &_msg) { Network *_network = new Network(this); // 通知业务层 connect(_network, &Network::sigReply, [this](const QString &_type_net, const QByteArray &_byte_array) { emit sigReply(_type_net, _byte_array); }); connect(_network, &Network::sigReplyError, [this](const QString &_type_net, const int &_error_code, const QString &_error_string) { emit sigReplyError(_type_net, _error_code, _error_string); }); connect(_network, &Network::sigTimeout, [this](const QString& _type) { emit sigTimeout(_type); }); _network->_setType(_msg._type); _network->_setCookieJar(&NetworkCookie::instance()); // 请求方式 if (_msg._method == "post") { _network->_post(_msg._url, _msg._byte); } else if (_msg._method == "get") { _network->_get(QUrl(_msg._url)); } }

3)cookie处理

#pragma once /********************************************************************* *@file NetworkCookie.h *@brief cookie *@author *@date *********************************************************************/ #include #include #include class NetworkCookie : public QNetworkCookieJar { Q_OBJECT public: static NetworkCookie& instance(); QList getCookies(); void setCookies(const QList& cookieList); private: NetworkCookie(QObject *parent); ~NetworkCookie(); }; #include "NetworkCookie.h" NetworkCookie::NetworkCookie(QObject *parent) : QNetworkCookieJar(parent) { } NetworkCookie::~NetworkCookie() { } NetworkCookie& NetworkCookie::instance() { static NetworkCookie _uniqueInstance(Q_NULLPTR); return _uniqueInstance; } QList NetworkCookie::getCookies() { return allCookies(); } void NetworkCookie::setCookies(const QList& cookieList) { if (this == NULL) return; this->setAllCookies(cookieList); } 3 业务逻辑模块 #pragma once /********************************************************************* *@file BusinessLogicManager.h *@brief 业务逻辑层 *@author *@date *********************************************************************/ #include #include #include class BusinessLogicManager : public QObject { Q_OBJECT public: explicit BusinessLogicManager(QObject *parent = nullptr); ~BusinessLogicManager(); void networkRequest(NetMessage&); Q_SIGNALS: /// @ 业务层->网络层(UI层通过业务层发送网络请求) void sigNetworkRequest(NetMessage&); public Q_SLOTS: // 网络请求返回成功消息通知 void on_comming_msg(const QString &_type, const QByteArray&); // 网络请求返回失败消息通知 void on_comming_error(const QString &_type, const int &_error_code, const QString &_error_string); // 网络请求超时消息通知 void on_comming_timeout(const QString &_type); Q_SIGNALS: void sigAskAction(bool, const QString&, int _error_code = 0); private: /// @发送文本消息 void onAskAction(const QString &_type, const QByteArray& _byte_array); } #include "BusinessLogicManager.h" #include "NetWorkLayer\NetworkCookie.h" BusinessLogicManager::BusinessLogicManager(QObject *parent) : QObject(parent) { } BusinessLogicManager::~BusinessLogicManager() { } void BusinessLogicManager::networkRequest(NetMessage&_msg) { emit sigNetRequest(_msg); } // 【这里如果请求过多 会出现打来你给ifelse,后续会出关于优化ifelse文章】 void BusinessLogicManager::on_comming_msg(const QString &_type, const QByteArray&_byte) { if (_type == NET_TYPE_ASK_ACTION) {// 网络请求成功 onAskAction(_type, _byte_array); } } void BusinessLogicManager::on_comming_error(const QString &_type, const int &_error_code, const QString &_error_string) { if (_type == NET_TYPE_ASK_ACTION) {// 网络请求错误通知 emit sigAskAction(false, tr("网络请求错误通知")); } } void BusinessLogicManager::on_comming_timeout(const QString &_type) { if (_type == NET_TYPE_ASK_ACTION) {// 超时处理 emit sigAskAction(false, tr("超时处理")); } } /** * 发送文本消息 */ void BusinessLogicManager::onAskAction(const QString &_type, const QByteArray& _byte_array) { // 这里是对网络请求返回的数据进行处理,然后通知UI模块 std::string _f = Jsonc::instance().getJsonValueStringByKey(Utils::byteArray2string(_byte_array), "f"); QString f = QString::fromStdString(_f); QString _context = tr("回复成功"); if (f == "0") { _context = tr("回复成功"); emit sigAskAction(true, tr("")); } else if (f == "2") { _context = tr("未登录"); emit sigReLogin(); } else if (f == "3") { _context = tr("字数大于80"); emit sigAskAction(false, tr("字数大于80")); } else if (f == "4") { _context = tr("内容为空"); emit sigAskAction(false, tr("内容为空")); } else if (f == "5") { _context = tr("3秒后再发言"); emit sigAskAction(false, tr("3秒后再发言")); } else if (f == "6") { _context = tr("您已被禁言"); emit sigAskAction(false, tr("您已被禁言")); } else if (f == "7") { _context = tr("未绑定手机号"); emit sigAskAction(false, tr("未绑定手机号")); } } 4 中间层 #pragma once /********************************************************************* *@file BridgeManager.h *@brief 中间控制层(UI、业务逻辑、网络) *@author *@date *********************************************************************/ #include #include "NetWorkLayer\NetworkManager.h" #include "BusinessLogicLayer\BusinessLogicManager.h" class BridgeManager : public QObject { Q_OBJECT public: static BridgeManager& instance(); // 得到网络层 和 业务逻辑层 实例 BusinessLogicManager* businessIns()const; NetworkManager* networkIns()const; private: BridgeManager(QObject *parent); ~BridgeManager(); private: NetworkManager *m_networkManager = nullptr; BusinessLogicManager *m_businessLogicManager = nullptr; }; #include "BridgeManager.h" BridgeManager::BridgeManager(QObject *parent) : QObject(parent) { m_businessLogicManager = new BusinessLogicManager(this); m_networkManager = new NetworkManager(this);//这里的实例化得注意了(this 会导致NetWork崩溃) // 业务层->网络层 connect(m_businessLogicManager, &BusinessLogicManager::sigNetworkRequest, m_networkManager, &NetworkManager::on_net_request_activated); // 网络层->业务层 connect(m_networkManager, &NetworkManager::sigReply, m_businessLogicManager, &BusinessLogicManager::on_comming_msg); connect(m_networkManager, &NetworkManager::sigReplyError, m_businessLogicManager, &BusinessLogicManager::on_comming_error); connect(m_networkManager, &NetworkManager::sigTimeout, m_businessLogicManager, &BusinessLogicManager::on_comming_timeout); } BridgeManager::~BridgeManager() { } BridgeManager& BridgeManager::instance() { static BridgeManager _uniqueInstance(Q_NULLPTR); return _uniqueInstance; } BusinessLogicManager* BridgeManager::businessIns()const { return m_businessLogicManager; } NetworkManager* BridgeManager::networkIns()const { return m_networkManager; }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有